﻿using S7.Net;
using S7.Net.Types;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Zhaoxi.FactoryDeviceSystem.Models;
using Zhaoxi.FactoryDeviceSystem.UControls;
using Zhaoxi.FactoryDeviceSystem.Utils;

namespace Zhaoxi.FactoryDeviceSystem
{

    public partial class FrmDevicesMain : Form
    {
        public FrmDevicesMain()
        {
            // 设置自动缩放模式为 Dpi 缩放
            this.AutoScaleMode = AutoScaleMode.Dpi;
            // 设置窗体的初始缩放比例为 150%（150 DPI）
            this.AutoScaleDimensions = new SizeF(96F, 96F);
            this.Font = new Font(this.Font.FontFamily, 12F); // 调整字体大小以适应缩放
            InitializeComponent();
        }

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED 
                return cp;
            }
        }


        #region 窗体尺寸调整
        const int WM_NCHITTEST = 0x0084;// 移动鼠标
        const int HTLEFT = 10;
        const int HTRIGHT = 11;
        const int HTTOP = 12;
        const int HTTOPLEFT = 13;
        const int HTTOPRIGHT = 14;
        const int HTBOTTOM = 15;
        const int HTBOTTOMLEFT = 0x10;
        const int HTBOTTOMRIGHT = 17;
        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            switch (m.Msg)
            {
                case WM_NCHITTEST:
                    if (this.MaximizeBox == true && this.WindowState == FormWindowState.Normal)
                    {
                        Point vPoint = new Point((int)m.LParam & 0xFFFF,
              (int)m.LParam >> 16 & 0xFFFF);
                        vPoint = PointToClient(vPoint);
                        if (vPoint.X <= 5)
                            if (vPoint.Y <= 5)
                                m.Result = (IntPtr)HTTOPLEFT;
                            else if (vPoint.Y >= ClientSize.Height - 5)
                                m.Result = (IntPtr)HTBOTTOMLEFT;
                            else m.Result = (IntPtr)HTLEFT;
                        else if (vPoint.X >= ClientSize.Width - 5)
                            if (vPoint.Y <= 5)
                                m.Result = (IntPtr)HTTOPRIGHT;
                            else if (vPoint.Y >= ClientSize.Height - 5)
                                m.Result = (IntPtr)HTBOTTOMRIGHT;
                            else m.Result = (IntPtr)HTRIGHT;
                        else if (vPoint.Y <= 5)
                            m.Result = (IntPtr)HTTOP;
                        else if (vPoint.Y >= ClientSize.Height - 5)
                            m.Result = (IntPtr)HTBOTTOM;
                    }
                    break;
            }
        }



        #endregion

        #region 控制功能
        /// <summary>
        /// 最小化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnMin_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }

        private void btnMax_Click(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Maximized)
            {
                this.WindowState = FormWindowState.Normal;
                btnMax.Text = "1";
            }
            else
            {
                this.WindowState = FormWindowState.Maximized;
                btnMax.Text = "2";
            }

        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// 系统退出
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FrmDevicesMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            //问题消息提示框
            if (MessageHelper.Question("系统退出", "你确定要退出系统吗？") == DialogResult.OK)
            {
                Application.ExitThread();
            }
            else
            {
                e.Cancel = true;
            }
        }

        #endregion

        #region 窗体拖动
        Point point = new Point();//按下时的点坐标
        bool isMove = false;//是否拖动中
        private void panelTop_MouseDown(object sender, MouseEventArgs e)
        {
            point = e.Location;//按住时的点
            isMove = true;//启动拖动
        }

        private void panelTop_MouseMove(object sender, MouseEventArgs e)
        {
            Point pointNew;
            if (e.Button == MouseButtons.Left && isMove)
            {
                pointNew = e.Location;//拖动到的点
                Point sPoint = new Point(pointNew.X - point.X, pointNew.Y - point.Y);//拖动的距离描述
                this.Location += new Size(sPoint);

            }
        }

        private void panelTop_MouseUp(object sender, MouseEventArgs e)
        {
            isMove = false;//释放拖动
        }

        #endregion

        System.Timers.Timer timer = null;//定时器
        Plc plc = null;
        bool isStart = false;//标识是否已启动监控
        Dictionary<int, bool> devStates = new Dictionary<int, bool>();//存储设备状态
        Dictionary<int, DeviceData> devDatas = new Dictionary<int, DeviceData>();//存储设备数据
        int runCount = 0, stopCount = 0;//统计运行设备数，停止设备数
        bool isFirst = true;//是否第一次加载
        List<AlarmInfo> alarmList= new List<AlarmInfo>();//报警记录集合
        private void FrmDevicesMain_Load(object sender, EventArgs e)
        {
            //加载PLC设置信息
            InitPLCSets();
            //加载设备配置
            CommonHelper.LoadDeviceList();
            //加载存储配置
            CommonHelper.LoadStoreSets();
            //加载设备列表和开关控制列表
            LoadDevicesAndControlList();
            timer = new System.Timers.Timer();
            timer.Interval = 1000;
            timer.Elapsed += Timer_Elapsed;
        }


        private void InitPLCSets()
        {
            if (CommonHelper.plcSet == null)
                CommonHelper.LoadPLCSet();
            if (CommonHelper.plcSet != null)
            {
                var plcSet = CommonHelper.plcSet;
                plc = new Plc(plcSet.CpuType, plcSet.Ip, plcSet.Port, plcSet.Rack, plcSet.Slot);
            }
        }

        //加载设备列表和开关控制列表
        private void LoadDevicesAndControlList()
        {
            if (CommonHelper.deviceList.Count > 0)
            {
                var deviceList = CommonHelper.deviceList.OrderBy(d => d.DeviceNo).ToList();
                flpDevList.Controls.Clear();
                flpSwitchList.Controls.Clear();
                foreach (var dev in deviceList)
                {
                    //创建设备呈现控件
                    UCDeviceControl deviceItem = CreateDevControl(dev);
                    flpDevList.Controls.Add(deviceItem);
                    //创建开关控制控件
                    UCDevSwitch switchItem = CreateSwitchControl(dev.DeviceNo, dev.DeviceName);
                    flpSwitchList.Controls.Add(switchItem);
                }
            }
        }

        //创建设备呈现控件对象
        private UCDeviceControl CreateDevControl(DeviceInfo dev)
        {
            UCDeviceControl deviceControl = new UCDeviceControl();
            deviceControl.Name = "dev" + dev.DeviceNo;
            deviceControl.InitDevice(dev.DeviceNo, dev.DeviceName);
            deviceControl.Margin = new Padding(5);
            deviceControl.Size = new Size(260, 140);
            return deviceControl;
        }

        //创建设备开关控件面板
        private UCDevSwitch CreateSwitchControl(int devNo, string devName)
        {
            UCDevSwitch switchItem = new UCDevSwitch();
            switchItem.DeviceNo = devNo;
            switchItem.DeviceName = devName;
            switchItem.CurState = false;//开关状态
            switchItem.CanOpen = true;
            switchItem.CanClose = false;
            switchItem.Margin = new Padding(8, 10, 5, 0);
            switchItem.Size = new Size(103, 70);
            switchItem.StartEvent += SwitchItem_StartEvent;
            switchItem.StopEvent += SwitchItem_StopEvent;
            return switchItem;
        }

        //启动设备  设备编号--- 状态地址
        private void SwitchItem_StartEvent(object sender, EventArgs e)
        {
             UCDevSwitch uc   = sender as UCDevSwitch;
            ChangeDevState(uc, true);
        }

        //停止设备
        private void SwitchItem_StopEvent(object sender, EventArgs e)
        {
            UCDevSwitch uc = sender as UCDevSwitch;
            ChangeDevState(uc, false);
        }

        //启停设备
        private void ChangeDevState(UCDevSwitch ucSwitch,bool state)
        {
             int devNo=ucSwitch.DeviceNo;//设备编号
             string stateAddr=CommonHelper.deviceList.Find(d=>d.DeviceNo==devNo).StateAddress;//状态地址
           // plc.Write("I" + stateAddr, state);
           // 直接调用 SafeWrite，添加错误处理逻辑
            bool success = SafeWrite("I" + stateAddr, state);
            if (!success)
            {
                // 根据场景选择处理方式：日志记录、UI提示或异常抛出
                //Log.Warning($"写入输入地址 I{stateAddr} 失败");
                // 或 MessageBox.Show("操作失败");
                Console.WriteLine($"写入输入地址 I{stateAddr} 失败");
            }
            if (state)
            {
                ucSwitch.CanOpen = false;
                ucSwitch.CanClose = true;
            }
            else
            {
                ucSwitch.CanOpen = true;
                ucSwitch.CanClose = false;
            }
        }

        //数据读取与加载
        private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            ReadAndLoadData();
        }

        private void ReadAndLoadData()
        {
            var devList = CommonHelper.deviceList;
            //数据的读取
            int count = devList.Count;
            //读状态
            var states = (BitArray)plc.Read(DataType.Input, 0, 0, VarType.Bit, count);

            //读设备数据 功率/速度/温度/压力
            ushort[] powers=new ushort[count];
            ushort[] speeds=new ushort[count];
            decimal[] temperatures=new decimal[count];
            decimal[] pressures=new decimal[count];

            //数据读取
            foreach(var para in CommonHelper.storeSets) {
                VarType vtype = (VarType)Enum.Parse(typeof(VarType), para.ReadType);
                if(para.ParaType=="Power")
                {
                    powers = (ushort[])plc.Read(DataType.DataBlock, 1, para.FirstPosition, vtype, count);
                }
                else if(para.ParaType=="Speed")
                {
                    speeds = (ushort[])plc.Read(DataType.DataBlock, 1, para.FirstPosition, vtype, count);
                }
                else if(para.ParaType=="Temperature")
                {
                    uint[] intTempers = (uint[])plc.Read(DataType.DataBlock, 1, para.FirstPosition, vtype, count);
                    temperatures=ConvertToDecimal(intTempers);
                }
                else if(para.ParaType=="Pressure")
                {
                    uint[] intPressures = (uint[])plc.Read(DataType.DataBlock, 1, para.FirstPosition, vtype, count);
                    pressures = ConvertToDecimal(intPressures);
                }
            }
             

            //存储处理
            for (int i = 0; i < devList.Count; i++)
            {
                //状态存储
                int pos = devList[i].Position;
                if (!devStates.ContainsKey(devList[i].DeviceNo))
                    devStates.Add(devList[i].DeviceNo, states[pos]);
                else
                    devStates[devList[i].DeviceNo]= states[pos];

                //数据存储
                DeviceData devData = new DeviceData();
                devData.Pressure = pressures[pos];
                devData.Temperature = temperatures[pos];
                devData.Power = powers[pos];
                devData.Speed = speeds[pos];
                if (!devDatas.ContainsKey(devList[i].DeviceNo))
                {
                    devDatas.Add(devList[i].DeviceNo, devData);
                }
                else
                    devDatas[devList[i].DeviceNo] = devData;
            }

            //设备信息的加载呈现
            LoadDeviceInfos();
        }


        private void LoadDeviceInfos()
        {
            this.Invoke(new Action(() =>
            {
                runCount = 0;
                stopCount = 0;
            
                //设备状态、数据加载
                foreach (Control c in flpDevList.Controls)
                {
                    UCDeviceControl devItem=c as UCDeviceControl;
                    if(devItem != null)
                    {
                        int devNo = devItem.DeviceNo;//设备编号
                       bool devState = devStates[devNo];//状态
                        if(devState)//运行
                        {
                            DeviceData devData = devDatas[devNo];
                            devItem.LoadData(devData, devState);//设备状态、数据加载
                            if(isFirst==false)
                            {
                                //数据实时检查
                                CheckData(devNo, devItem.DeviceName, devData);
                            }
                            runCount++;
                        }
                        else //停止
                        {
                            devItem.ClearData();//清空数据
                            devItem.RunState = false;
                            stopCount++;
                        }
                    }
                }
                if (isFirst)//第一次加载
                {
                    //初始化数据检测
                    InitCheckData();
                }
                //开关面板状态加载
                foreach (Control c in flpSwitchList.Controls)
                {
                    UCDevSwitch devSwitch=c as UCDevSwitch;
                    if(devSwitch != null)
                    {
                        int devNo= devSwitch.DeviceNo;
                        devSwitch.CurState = devStates[devNo];//运行状态
                        if( devSwitch.CurState )
                        {
                            devSwitch.CanOpen = false;
                            devSwitch.CanClose = true;
                        }
                        else
                        {
                            devSwitch.CanOpen = true;
                            devSwitch.CanClose = false;
                        }
                    }
                }

                //呈现统计的设备数
                txtRunCount.DataValue = runCount.ToString();
                txtStopCount.DataValue = stopCount.ToString();

                isFirst = false;//不是第一次加载
            }));
        }

    
        Dictionary<int, DeviceData> lastDatas = new Dictionary<int, DeviceData>();//最近的数据
        //信息初始化检测
       private void InitCheckData()
        {
            foreach(int devNo in devDatas.Keys)
            {
                if (devStates[devNo]==true)
                {
                    if(!lastDatas.ContainsKey(devNo))
                        lastDatas.Add(devNo, devDatas[devNo]);
                    DeviceData data = devDatas[devNo];
                    string devName=CommonHelper.deviceList.Find(d=>d.DeviceNo==devNo).DeviceName;
                    if(data.Temperature>30)//温度过高
                    {
                        //添加异常记录
                        AlarmInfo alarm = new AlarmInfo(devNo, devName, "温度过高", data.Temperature.ToString("0.0"));
                        AddAlarmInfo(alarm);
                    }
                    if(data.Pressure<3)//压力过低
                    {
                        AlarmInfo alarm = new AlarmInfo(devNo, devName, "压力过低", data.Pressure.ToString("0.00"));
                        AddAlarmInfo(alarm);
                    }
                    else if(data.Pressure>16)//压力过高
                    {
                        AlarmInfo alarm = new AlarmInfo(devNo, devName, "压力过高", data.Pressure.ToString("0.00"));
                        AddAlarmInfo(alarm);
                    }
                    if(data.Speed<300)
                    {
                        AlarmInfo alarm = new AlarmInfo(devNo, devName, "速度过慢", data.Speed.ToString());
                        AddAlarmInfo(alarm);
                    }
                    else if(data.Speed>1000)
                    {
                        AlarmInfo alarm = new AlarmInfo(devNo, devName, "速度过快", data.Speed.ToString());
                        AddAlarmInfo(alarm);
                    }
                }
            }
        }

        //实时检测方法
        private void CheckData(int devNo, string devName, DeviceData devData)
        {
            if (!lastDatas.ContainsKey(devNo))
                lastDatas.Add(devNo, devData);
            var lastData = lastDatas[devNo];//上一次的数据
            if(devData.Temperature>30&&lastData.Temperature<=30)//温度 上一次正常，这一次异常
            {
                AlarmInfo alarm = new AlarmInfo(devNo, devName, "温度过高", devData.Temperature.ToString("0.0"));
                AddAlarmInfo(alarm);
            }
            else if(lastData.Temperature>30&&devData.Temperature<=30)
            {
                AlarmInfo alarm = new AlarmInfo(devNo, devName,"取消报警", "温度正常", devData.Temperature.ToString("0.0"));
                AddAlarmInfo(alarm);
            }

            //压力 现在过高异常，上一次正常
            if(devData.Pressure>16 && (lastData.Pressure<=16&&lastData.Pressure>=3))
            {
                AlarmInfo alarm = new AlarmInfo(devNo, devName, "压力过高", devData.Pressure.ToString("0.00"));
                AddAlarmInfo(alarm);
            }
            else if(lastData.Pressure > 16 && (devData.Pressure <= 16 && devData.Pressure >= 3))
            {
                AlarmInfo alarm = new AlarmInfo(devNo, devName, "取消报警", "压力正常", devData.Pressure.ToString("0.00"));
                AddAlarmInfo(alarm);
            }

            if (devData.Pressure <3 && (lastData.Pressure <= 16 && lastData.Pressure >= 3))
            {
                AlarmInfo alarm = new AlarmInfo(devNo, devName, "压力过低", devData.Pressure.ToString("0.00"));
                AddAlarmInfo(alarm);
            }
            else if (lastData.Pressure <3 && (devData.Pressure <= 16 && devData.Pressure >= 3))
            {
                AlarmInfo alarm = new AlarmInfo(devNo, devName, "取消报警", "压力正常", devData.Pressure.ToString("0.00"));
                AddAlarmInfo(alarm);
            }

            //速度 现在过快异常，上一次正常
            if (devData.Speed > 1000 && (lastData.Speed <= 1000 && lastData.Speed >= 300 ))
            {
                AlarmInfo alarm = new AlarmInfo(devNo, devName, "速度过快", devData.Speed.ToString());
                AddAlarmInfo(alarm);
            }
            else if (lastData.Speed > 1000 && (devData.Speed <= 1000 && devData.Speed >= 300))
            {
                AlarmInfo alarm = new AlarmInfo(devNo, devName, "取消报警", "速度正常", devData.Speed.ToString());
                AddAlarmInfo(alarm);
            }

            if (devData.Speed < 300 && (lastData.Speed <= 1000 && lastData.Speed >= 300))
            {
                AlarmInfo alarm = new AlarmInfo(devNo, devName, "速度过慢", devData.Speed.ToString());
                AddAlarmInfo(alarm);
            }
            else if (lastData.Speed < 300 && (devData.Speed <= 1000 && devData.Speed >= 300))
            {
                AlarmInfo alarm = new AlarmInfo(devNo, devName, "取消报警", "速度正常", devData.Speed.ToString());
                AddAlarmInfo(alarm);
            }
            lastDatas[devNo] = devData;
        }



        //添加报警记录
        private void AddAlarmInfo(AlarmInfo alarm)
        {
             if(alarmList.Count<=20)
            {
                alarmList.Add(alarm);
            }
            else
            {
                alarmList.RemoveAt(0);
                alarmList.Add(alarm);
            }
            ReloadAlarmList();//刷新报警列表
        }

        private void ReloadAlarmList()
        {
            if(dgvAlarmList.AutoGenerateColumns==true)
                 dgvAlarmList.AutoGenerateColumns = false;
            dgvAlarmList.DataSource = null;
            dgvAlarmList.DataSource= alarmList;
        }
      

        //打开通信设置子窗口
        private void btnPLCSetting_Click(object sender, EventArgs e)
        {
            if (plc != null && plc.IsConnected)
            {
                timer.Stop();
                plc.Close();
            }
            FrmPLCSetting frmPLCSetting = new FrmPLCSetting();
            frmPLCSetting.ShowDialog();
            if (CommonHelper.plcSet != null)
            {
                InitPLCSets();
            }
        }

        /// <summary>
        /// 打开设备配置子窗口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDeviceSetting_Click(object sender, EventArgs e)
        {
            if (isStart)
            {
                //关闭
                isStart = false;
                timer.Stop();
                plc.Close();
            }
            FrmDeviceSetting frmDeviceSetting = new FrmDeviceSetting();
            frmDeviceSetting.ShowDialog();
            if (CommonHelper.IsUpdateDevices)
            {
                //重新加载设备列表和开关控制列表
                LoadDevicesAndControlList();
            }
        }

        /// <summary>
        /// 打开存储配置子窗口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStoreSetting_Click(object sender, EventArgs e)
        {
            if (isStart)
            {
                //停止监控
                isStart = false;
                timer.Stop();
                plc.Close();
            }
            FrmStoreSetting frmStoreSetting = new FrmStoreSetting();
            frmStoreSetting.ShowDialog();

        }

        /// <summary>
        /// 启动或停止监控
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCollection_Click(object sender, EventArgs e)
        {
            if (plc != null)
            {
                try
                {
                    if (!isStart)
                    {
                        plc.Open();//打开连接
                        if (plc.IsConnected)
                        {
                            lblConnection.Text = "已连接";
                            isStart = true;
                            timer.Start();
                            btnCollection.Text = "停止监控";
                            btnCollection.BgColor = Color.Brown;
                            btnCollection.BgColor2 = Color.Maroon;
                        }
                        else
                        {
                            lblConnection.Text = "未连接";
                        }
                    }
                    else
                    {
                        timer.Stop();
                        plc.Close();//关闭连接
                        isStart = false;
                        btnCollection.Text = "启动监控";
                        lblConnection.Text = "未连接";
                        btnCollection.BgColor = Color.RoyalBlue;
                        btnCollection.BgColor2 = Color.MidnightBlue;
                    }
                }
                catch (Exception ex)
                {
                    MessageHelper.Error("启动异常", ex.Message);
                    return;
                }

            }
            else
            {
                MessageHelper.Error("连接错误", "PLC未进行配置！");
                return;
            }
        }


        //全开功能
        private void btnAllOpen_Click(object sender, EventArgs e)
        {
            DataItem[] dataItems = CreateStateDataItems(true);
            //plc.Write(dataItems);
            SafeWriteBulk(dataItems);
        }

        //全关功能
        private void btnAllClose_Click(object sender, EventArgs e)
        {
            DataItem[] dataItems = CreateStateDataItems(false);
            //plc.Write(dataItems);
            SafeWriteBulk(dataItems);
        }

        //创建批量开关功能的数组
        //private DataItem[] CreateStateDataItems(bool state)
        //{
        //    List<DataItem> dataItems = new List<DataItem>();
        //    var devList = CommonHelper.deviceList;
        //    for (int i = 0; i < devList.Count; i++)
        //    {
        //        DataItem item = new DataItem();
        //        item.DataType = DataType.Input;
        //        item.VarType = VarType.Bit;
        //        item.DB = 0;
        //        //StateAddr  状态地址 1.0
        //        string stateAddr = devList[i].StateAddress;
        //        item.StartByteAdr = stateAddr.Split('.')[0].GetInt();
        //        item.BitAdr = stateAddr.Split('.')[1].GetByte();
        //        item.Value = state;
        //        dataItems.Add(item);
        //    }
        //    return dataItems.ToArray();
        //}

        ///创建批量开关功能的数组(更新了device.StateAddress解析)
        private DataItem[] CreateStateDataItems(bool state)
        {
            var dataItems = new List<DataItem>();
            foreach (var device in CommonHelper.deviceList)
            {
                // 解析地址（此处假设device.StateAddress已经是完整地址，如"Q1.0"）
                var (dataType, byteAddr, bitAddr) = AddressParser.Parse(device.StateAddress);

                dataItems.Add(new DataItem
                {
                    DataType = dataType,
                    VarType = VarType.Bit,
                    DB = 0,
                    StartByteAdr = byteAddr,
                    BitAdr = bitAddr,
                    Value = state
                });
            }
            return dataItems.ToArray();
        }

        private decimal[] ConvertToDecimal(uint[] intVals)
        {
            List<decimal> result = new List<decimal>();
            foreach (uint val in intVals) {
                byte[] arr = BitConverter.GetBytes(val);
                float fVal=BitConverter.ToSingle(arr, 0);
                result.Add((decimal)fVal);
            }
            return result.ToArray();
        }

        private void panelTop_Paint(object sender, PaintEventArgs e)
        {

        }

        //行中报警状态文字颜色
        private void dgvAlarmList_DataSourceChanged(object sender, EventArgs e)
        {
            for (int i = 0;i<dgvAlarmList.Rows.Count;i++)
            {
                AlarmInfo alarm = dgvAlarmList.Rows[i].DataBoundItem as AlarmInfo;
                if(alarm.AlarmState=="报警")
                {
                    dgvAlarmList.Rows[i].Cells["colAlarmState"].Style.ForeColor = Color.DarkRed;
                }
                else
                {
                    dgvAlarmList.Rows[i].Cells["colAlarmState"].Style.ForeColor = Color.Green;
                }
            }
        }

        // 封装安全的Write方法
        // 该方法用于安全地向PLC（可编程逻辑控制器）写入数据，当写入失败时会进行重试操作
        // 参数 address: 要写入的PLC地址，类型为字符串
        // 参数 state: 要写入的状态值，类型为布尔值
        // 参数 maxRetries: 最大重试次数，默认为3次
        private bool SafeWrite(string address, bool state, int maxRetries = 3)
        {
            // 初始化重试计数器，记录当前重试的次数
            int retryCount = 0;
            // 进入循环，只要重试次数小于最大重试次数，就会继续尝试写入操作
            while (retryCount < maxRetries)
            {
                try
                {
                    // 调用PLC的Write方法，尝试将指定状态写入到指定地址
                    plc.Write(address, state);
                    // 如果写入操作没有抛出异常，说明写入成功，返回true
                    return true;
                }
                catch (PlcException ex)
                {
                    // 如果写入过程中抛出了PLC通信异常，说明写入失败，重试次数加1
                    retryCount++;
                    // 检查重试次数是否已经达到或超过最大重试次数
                    if (retryCount >= maxRetries)
                    {
                        // 如果达到最大重试次数，使用日志记录工具记录错误信息，包含失败的地址和异常信息
                        Console.WriteLine($"写入PLC地址 {address} 失败: {ex.Message}");
                        // 写入失败，返回false
                        return false;
                    }
                    // 如果还未达到最大重试次数，线程暂停1秒（1000毫秒），给PLC和网络一些时间恢复，然后进行下一次重试
                    Thread.Sleep(1000);
                }
            }
            // 如果循环结束后仍然没有成功写入，说明写入失败，返回false
            return false;
        }
        // 新增批量安全写入方法
        public bool SafeWriteBulk(DataItem[] dataItems, int maxRetries = 3)
        {
            int retryCount = 0;
            while (retryCount < maxRetries)
            {
                try
                {
                    plc.Write(dataItems);
                    return true;
                }
                catch (PlcException ex)
                {
                    retryCount++;
                    if (retryCount >= maxRetries)
                    {
                        Console.WriteLine($"批量写入失败: {ex.Message}");
                        return false;
                    }
                    Thread.Sleep(1000);
                }
            }
            return false;
        }
    //修复bug

    }
}
